package com.dudu.access;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.UUID;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.dudu.bean.DialResultBean;
import com.dudu.bean.ResponseSendVoiceBean;
import com.dudu.enumeration.RemindEnum;
import com.dudu.service.ILogService;
import com.dudu.service.impl.LogService;
import com.dudu.utils.DateUtils;
import com.dudu.utils.EnumUtility;
import com.dudu.utils.HttpRequest;

import core.CoreService;
import core.util.DateUtil;

/**
 * 荣联通道Util
 * 
 * @author gaoxs
 * 
 */
public class RongLianUtils {
    private static ILogService logService = new LogService();
    private static ResourceBundle resourceBundle = PropertyResourceBundle.getBundle("voicenoticeconfig");
    private static String AccountSid = resourceBundle.getString("AccountSid"); // 主帐号
    private static String AccountToken = resourceBundle.getString("AccountToken"); // 主帐号token
    private static String SubAccountSid = resourceBundle.getString("SubAccountSid"); // 子帐号
    private static String SubAccountToken = resourceBundle.getString("SubAccountToken"); // 子帐号token
    private static String AppId = resourceBundle.getString("AppId"); // 应用ID
    private static String ServerIP = resourceBundle.getString("ServerIP");
    private static String ServerPort = resourceBundle.getString("ServerPort");
    private static String SoftVersion = resourceBundle.getString("SoftVersion");
    private static String timestamp = "";

    public static void main(String[] args) throws UnsupportedEncodingException, DocumentException {
	// RongLianUtils.UploadFile("testDD", "D:\\testdudu.wav");
	RongLianUtils.VoiceNotice("11662187762", "", "研究发现,人产生困意的一个主要原因是体内温度的降低,睡前1小时冲个热水澡让体内温度升高,之后逐渐冷却,让人产生困意,满意请按1,不满意请按2,,重听请按井号键", "1", "17001090122", "", "");
	// RongLianUtils.dial("17001090130", "075582385383-6556", "", "", "");
	// RongLianUtils.IvrDial("17001090122", "01062434316", "", "", "",
	// "满意请按1;不满意请按2", "", "1",
	// "http://123.103.9.189:5231/rlcallback/BillCallBack.do", "1");
	// String called="07558238538316556";
	// System.out.println(called.replace("a", "-"));
    }

    /**
     * 荣联语音通知
     * 
     * @param called
     *            被叫（被叫号码，被叫为座机时需要添加区号，
     *            如：01052823298；被叫为分机时分机号由‘-’隔开，如：01052823298-3627）
     * @param mediaName
     *            语音文件名称，格式 wav，播放多个文件用英文分号隔开。与mediaTxt不能同时为空。当不为空时mediaTxt属性失效
     * @param mediaTxt
     *            文本内容，文本中汉字要求utf8编码
     * @param playMode
     *            是否同时播放文本和语音文件,优先播放文本( 0、否 1、是，默认0)。
     * @param displayNum
     *            来电显示的号码
     * @param respUrl
     *            外呼通知状态通知回调地址（必须符合URL规范），云通讯平台将向该Url地址发送呼叫结果通知。
     * @param userData
     *            第三方私有数据，可在外呼通知状态通知中获取此参数。
     * @return
     */
    public static ResponseSendVoiceBean VoiceNotice(String called, String mediaName, String mediaTxt, String playMode, String displayNum, String respUrl, String userData) {
	ResponseSendVoiceBean responseSendVoice = new ResponseSendVoiceBean();
	// 拼接请求包体
	String requsetbody = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?><LandingCall>");
	sb.append("<appId>").append(AppId).append("</appId>");// 应用ID
	sb.append("<to>").append(called.replace("a", "-")).append("</to>");// 被叫号码
	// mediaName 语音文件名称，格式 wav，播放多个文件用英文分号隔开。
	// 与mediaTxt不能同时为空。当不为空时mediaTxt属性失效
	if (EnumUtility.isNotBlank(mediaName)) {
	    sb.append("<mediaName>").append(mediaName).append("</mediaName>");
	}
	// 本内容，文本中汉字要求utf8编码，默认值为空
	if (EnumUtility.isNotBlank(mediaTxt)) {
	    sb.append("<mediaTxt>").append(mediaTxt).append("</mediaTxt>");
	}
	// 来电显示的号码
	sb.append("<displayNum>").append(displayNum.trim()).append("</displayNum>");
	// 循环播放次数，1－3次，默认播放1次。
	sb.append("<playTimes>").append("1").append("</playTimes>");
	// 外呼通知状态通知回调地址
	if (EnumUtility.isNotBlank(respUrl)) {
	    sb.append("<respUrl>").append(respUrl).append("</respUrl>");
	}
	// 第三方私有数据
	if (EnumUtility.isNotBlank(userData)) {
	    sb.append("<userData>").append(userData).append("</userData>");
	}
	// 最大通话时长
	// sb.append("<maxCallTime>").append("60").append("</maxCallTime>");
	// 文本转语音后的发音速度，取值范围：-500至500，当mediaTxt有效才生效。
	sb.append("<txtSpeed>").append("-500").append("</txtSpeed>");
	// 文本转语音后的音量大小，取值范围：-500至500，当mediaTxt有效才生效
	sb.append("<txtVolume>").append("0").append("</txtVolume>");
	// 文本转语音后的音调，取值范围：-500至500，当mediaTxt有效才生效。
	// sb.append("<txtPitch>").append("100").append("</txtPitch>");
	// 文本转语音后的背景音编号，目前云通讯平台支持6种背景音，1到6的六种背景音编码，0为不需要背景音
	sb.append("<txtBgsound>").append("0").append("</txtBgsound>");
	// playMode是否同时播放文本和语音文件 , 0、否 1、是，默认0。优先播放文本。
	if (EnumUtility.isNotBlank(playMode)) {
	    sb.append("<playMode>").append(playMode).append("</playMode>");
	}
	sb.append("</LandingCall>").toString();
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/Calls/LandingCalls?sig=" + getSignature(AccountSid, AccountToken);
	long begin = Calendar.getInstance().getTimeInMillis();
	String response = HttpRequest.sendRongLianPost(AccountSid, timestamp, url, requsetbody);
	remind(response, RemindEnum.OPEN_VOICE_RONGLIAN.getKey(), RemindEnum.OPEN_VOICE_RONGLIAN.getValue());
	long end = Calendar.getInstance().getTimeInMillis();
	String result = "";
	String sessionid = "";
	if (StringUtils.isNotBlank(response)) {
	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		result = root.elementTextTrim("statusCode");
		if (result.equals("000000")) {
		    Element LandingCall = root.element("LandingCall");
		    sessionid = LandingCall.elementTextTrim("callSid");
		    result = "0";
		} else {
		    result = "-1";
		    responseSendVoice.setDesc(root.elementTextTrim("statusMsg"));
		}
	    } catch (DocumentException e) {
		e.printStackTrace();
		result = "-1";
		responseSendVoice.setDesc(e.getMessage());
	    }
	} else {
	    result = "-1";
	    response = "";
	    responseSendVoice.setDesc("接口响应为空");
	}
	double time = Double.valueOf((end - begin)) / 1000;
	logService.logIms(time, "RongLianNotice", "【" + requsetbody.toString() + "】", "【" + response + "】", result, DateUtils.getCurrentTime(), "RongLian", called);
	responseSendVoice.setResult(result);
	responseSendVoice.setSessionid(sessionid);
	return responseSendVoice;
    }

    /**
     * 荣联IVR外呼
     * 
     * @param called
     *            被叫号码,多个号码之间以英文分号分隔，单次提交号码上限500。重复号码只呼叫一次
     * @param displayNum
     *            用户侧显示号码
     * @param startDate
     *            开始时间 格式2014-08-20 14:20:20
     * @param endDate
     *            结束时间 格式2014-08-21 14:20:20
     * @param preText
     *            内容数据，用于替换ttsText中{序号}
     *            ，没有内容直接加分号，多个以英文分号分隔，数量和called数量相等。播放内容不允许有分号
     * @param ttsText
     *            文本内容，文本中汉字要求utf8编码，默认值为空。当playMode为0时且mediaName为空才有效。
     * @param mediaName
     *            语音文件名称，格式 wav。与ttsText不能同时为空。当playMode为0时此参数不为空时ttsText属性失效
     * @param callMode
     *            当前时间超过endDate后是否还继续外呼任务 0、否 1、是
     *            默认0，为1时在时间内呼叫不完的后在时间外继续外呼，直到所有呼叫完成为止
     * @param respUrl
     *            回调地址
     * @param recvDigits
     *            接收按键个数：0为不接收按键；非0正整数为接收的按键个数，例如2为接收2个按键，用户按2个键才会在话单回调中有按键信息
     * @return
     */
    public static ResponseSendVoiceBean IvrDial(String called, String displayNum, String startDate, String endDate, String preText, String ttsText, String mediaName,
	    String callMode, String respUrl, String recvDigits) {
	ResponseSendVoiceBean responseSendVoice = new ResponseSendVoiceBean();
	String result = "";
	String sessionid = UUID.randomUUID().toString().toUpperCase();
	// 拼接请求包体
	String requsetbody = "";
	String desc = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?><PrepareDial>");
	sb.append("<appId>").append(AppId).append("</appId>");// 应用ID
	// sb.append("<taskName>test</taskName>");//任务名称（至多64个字符），默认生成32位随机数
	sb.append("<called>").append(called.replace("a", "-")).append("</called>");// 被叫号码,多个号码之间以英文分号分隔，单次提交号码上限500。重复号码只呼叫一次
	// 来电显示的号码
	sb.append("<disnumber>").append(displayNum.trim()).append("</disnumber>");
	if (StringUtils.isBlank(startDate)) {
	    startDate = DateUtils.getCurrentTime();
	}
	// 开始时间 格式2014-08-20 14:20:20
	sb.append("<startDate>").append(startDate).append("</startDate>");
	if (StringUtils.isBlank(endDate)) {
	    try {
		endDate = DateUtil.afterMinitStr(startDate, "yyyy-MM-dd HH:mm:ss", 1);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
	// 结束时间 格式2014-08-21 14:20:20
	sb.append("<endDate>").append(endDate).append("</endDate>");
	// 呼叫最大并发数，最大100，缺省5
	sb.append("<callConcurrent>").append("20").append("</callConcurrent>");
	// 内容数据，用于替换ttsText中{序号} ，没有内容直接加分号，多个以英文分号分隔，数量和called数量相等。播放内容不允许有分号
	if (StringUtils.isBlank(preText)) {
	    sb.append("<preText>").append(";").append("</preText>");

	} else {
	    sb.append("<preText>").append(preText).append("</preText>");
	}
	// 文本内容，文本中汉字要求utf8编码，默认值为空。当playMode为0时且mediaName为空才有效。
	sb.append("<ttsText>").append(ttsText).append("</ttsText>");
	// 语音文件名称，格式 wav。与ttsText不能同时为空。当playMode为0时此参数不为空时ttsText属性失效
	sb.append("<mediaName>").append(mediaName).append("</mediaName>");
	// 播放次数，播放1到3次，默认1次
	sb.append("<playtimes>").append("1").append("</playtimes>");
	// 是否同时播放文本和语音文件0、否 1、是，默认0优先播放语音文件，1为先播放文本再播放语音文件。当recvDigits为0时有效。
	sb.append("<playMode>").append("1").append("</playMode>");
	// 当前时间超过endDate后是否还继续外呼任务 0、否 1、是 默认0，为1时在时间内呼叫不完的后在时间外继续外呼，直到所有呼叫完成为止
	sb.append("<callMode>").append(callMode).append("</callMode>");
	// 回调地址
	sb.append("<callNotifyUrl>").append(respUrl).append("</callNotifyUrl>");
	// 接收按键个数：0为不接收按键；非0正整数为接收的按键个数，例如2为接收2个按键，用户按2个键才会在话单回调中有按键信息
	sb.append("<recvDigits>").append(recvDigits).append("</recvDigits>");
	// 接收按键超时时间，默认10s，最大30s。
	sb.append("<digitsTimeout>").append("15").append("</digitsTimeout>");
	// 挂机前播放的语音文件。
	sb.append("<hangupMediaName>").append("201610091054514232.wav").append("</hangupMediaName>");
	// session_id
	sb.append("<userdata>").append(sessionid).append("</userdata>");
	sb.append("</PrepareDial>").toString();
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/Calls/PrepareDial?sig=" + getSignature(AccountSid, AccountToken);
	long begin = Calendar.getInstance().getTimeInMillis();
	String response = HttpRequest.sendRongLianPost(AccountSid, timestamp, url, requsetbody);
	remind(response, RemindEnum.OPEN_IVRDIAL_RONGLIAN.getKey(), RemindEnum.OPEN_IVRDIAL_RONGLIAN.getValue());
	long end = Calendar.getInstance().getTimeInMillis();

	if (StringUtils.isNotBlank(response)) {
	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		result = root.elementTextTrim("statusCode");
		if (result.equals("000000")) {
		    result = "0";
		    desc = "OK";
		} else {
		    result = "-1";
		    sessionid = "";
		    desc = root.elementTextTrim("statusMsg");
		}
	    } catch (DocumentException e) {
		e.printStackTrace();
		result = "-1";
		sessionid = "";
		desc = e.getMessage();
	    }
	} else {
	    result = "-1";
	    sessionid = "";
	    response = "";
	    desc = "接口响应为空";
	}
	double time = Double.valueOf((end - begin)) / 1000;
	logService.logIms(time, "RongLianIvrDail", "【" + requsetbody.toString() + "】", "【" + response + "】", result, DateUtils.getCurrentTime(), "RongLian", called);
	responseSendVoice.setResult(result);
	responseSendVoice.setSessionid(sessionid);
	responseSendVoice.setDesc(desc);
	return responseSendVoice;
    }

    /**
     * 容联网页回呼（点击拨号、两方通话）
     * 
     * @param caller
     *            主叫
     * @param called
     *            被叫
     * @param customerSerNum
     * @param fromSerNum
     * @param ticketUrl
     * @param needRecord
     *            是否录音：0表示不录音；1表示录音；默认值0
     * @param display_mode
     *            1：显示主叫号码、0：显示平台配置号码
     * @return
     */
    public static DialResultBean dial(String caller, String called, String displayNum, String ticketUrl, String needRecord, String display_mode) {
	DialResultBean resultBean = new DialResultBean();
	// 拼接请求包体
	String requsetbody = "";
	String desc = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?>");
	sb.append("<CallBack>");
	sb.append("<from>").append(caller.replace("a", "-")).append("</from>"); // 主叫
	sb.append("<to>").append(called.replace("a", "-")).append("</to>"); // 被叫
	// 来电显示的号码
	sb.append("<fromSerNum>").append(displayNum.trim()).append("</fromSerNum>"); // 主叫侧显示的号码
	if (StringUtils.isNotBlank(display_mode) && display_mode.equals("1")) {

	    if (caller.indexOf("14") == 0 || caller.indexOf("17") == 0 || caller.indexOf("8614") == 0 || caller.indexOf("8617") == 0) {
		sb.append("<customerSerNum>").append(displayNum.trim()).append("</customerSerNum>"); // 被叫侧显示的号码
	    } else {
		sb.append("<customerSerNum>").append("").append("</customerSerNum>"); // 被叫侧显示的号码
	    }
	} else {
	    sb.append("<customerSerNum>").append(displayNum.trim()).append("</customerSerNum>"); // 被叫侧显示的号码
	}
	// sb.append("<promptTone>").append(promptTone).append("</promptTone>");
	// //第三方自定义回拨提示音
	// sb.append("<alwaysPlay>").append(alwaysPlay).append("</alwaysPlay>");
	// //是否一直播放提示音
	// sb.append("<terminalDtmf>").append(terminalDtmf).append("</terminalDtmf>");
	// //用于终止播放promptTone参数定义的提示音，主叫通过指定按键终止播放当前提示音，强制听被叫回铃音。只有当被叫振铃按键才有效，默认值为空。
	// sb.append("<userData>").append(userData).append("</userData>");
	// //第三方私有数据，支持英文字母和数字，长度最大支持256字节。
	// sb.append("<maxCallTime>").append(maxCallTime).append("</maxCallTime>");
	// //通话的最大时长,单位为秒。
	sb.append("<hangupCdrUrl>").append(ticketUrl).append("</hangupCdrUrl>"); // 实时话单通知接口回调地址
	sb.append("<needBothCdr>").append("1").append("</needBothCdr>"); // 是否给主被叫发送话单：0表示发送主叫话单；1表示发送主被叫话单；
									 // 默认值0。
	sb.append("<needRecord>").append(needRecord).append("</needRecord>"); // 是否录音：0表示不录音；1表示录音；默认值0
	// sb.append("<countDownTime>").append(countDownTime).append("</countDownTime>");
	// //设置倒计时时间，单位秒
	// sb.append("<countDownPrompt>").append(countDownPrompt).append("</countDownPrompt>");
	// //wav格式的文件名，第三方自定义倒计时提示音
	sb.append("<recordPoint>").append("1").append("</recordPoint>"); // 主叫接听还是被叫接听开始录音：0表示主叫接听开始录音；1表示被叫接听开始录音；默认值0。
	// sb.append("<cbContenType>").append(cbContenType).append("</cbContenType>");
	// //话单报文格式，取值xml、json。默认xml。只针对实时话单通知有效。
	sb.append("</CallBack>");
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/SubAccounts/" + SubAccountSid + "/Calls/Callback?sig="
		+ getSignature(SubAccountSid, SubAccountToken);

	long begin = Calendar.getInstance().getTimeInMillis();
	String response = HttpRequest.sendRongLianPost(SubAccountSid, timestamp, url, requsetbody);
	remind(response, RemindEnum.OPEN_DIAL_RONGLIAN.getKey(), RemindEnum.OPEN_DIAL_RONGLIAN.getValue());
	long end = Calendar.getInstance().getTimeInMillis();
	String result = "";
	String sessionid = "";
	if (StringUtils.isNotBlank(response)) {
	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		result = root.elementTextTrim("statusCode");
		if (result.equals("000000")) {
		    Element callBack = root.element("CallBack");
		    sessionid = callBack.elementTextTrim("callSid");
		    result = "0";
		    desc = "OK";
		} else {
		    result = "-1";
		    desc = root.elementTextTrim("statusMsg");
		}
	    } catch (DocumentException e) {
		e.printStackTrace();
	    }
	} else {
	    result = "-1";
	    response = "";
	    desc = "接口响应为空";
	}
	double time = Double.valueOf((end - begin)) / 1000;
	logService.logIms(time, "Dial", "【" + requsetbody.toString() + "】", "【" + response + "】", result, DateUtils.getCurrentTime(), "RongLian", caller);

	resultBean.setDisplayNbr(displayNum);
	resultBean.setResult(result);
	resultBean.setSessionId(sessionid);
	resultBean.setDesc(desc);
	return resultBean;
    }

    /**
     * 结束通话
     * 
     * @param sessionId
     * @return
     */
    public static JSONObject dialStop(String sessionId) {
	JSONObject object = new JSONObject();
	// 拼接请求包体
	String requsetbody = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?><CallCancel>");
	sb.append("<appId>" + AppId + "</appId>");
	sb.append("<type>0</type>");// 0： 任意时间都可以挂断电话；1
				    // ：被叫应答前可以挂断电话，其他时段返回错误代码；2：
				    // 主叫应答前可以挂断电话，其他时段返回错误代码；默认值为0。
	sb.append("<callSid>" + sessionId + "</callSid></CallCancel>");
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/SubAccounts/" + SubAccountSid + "/Calls/CallCancel?sig="
		+ getSignature(SubAccountSid, SubAccountToken);
	long begin = Calendar.getInstance().getTimeInMillis();
	String response = HttpRequest.sendRongLianPost(SubAccountSid, timestamp, url, requsetbody);
	long end = Calendar.getInstance().getTimeInMillis();
	String result = "";
	if (StringUtils.isNotBlank(response)) {
	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		result = root.elementTextTrim("statusCode");
		if (result.equals("000000")) {
		    result = "0";
		} else {
		    result = "-1";
		}
	    } catch (DocumentException e) {
		e.printStackTrace();
	    }
	} else {
	    result = "-1";
	    response = "";
	}
	double time = Double.valueOf((end - begin)) / 1000;
	logService.logIms(time, "DailStop", "【" + requsetbody.toString() + "】", "【" + response + "】", result, DateUtils.getCurrentTime(), "RongLian", "");
	object.put("result", result);
	object.put("discripe", "");
	return object;

    }

    /**
     * 上传文件 1、先把mp3格式转成wav 2、把文件转成二进制流
     * 
     * @param fileName
     * @param completeFileName
     * @return
     */
    public static ResponseSendVoiceBean UploadFile(String fileName, String completeFileName) {
	fileName = fileName + ".wav";
	ResponseSendVoiceBean bean = new ResponseSendVoiceBean();
	String currentTime = DateUtils.getCurrentTime();
	// 记录发起的开始时间
	Long begin = Calendar.getInstance().getTimeInMillis();
	try {
	    // 判断是否为mp3文件
	    if (completeFileName.endsWith("mp3")) {
		CoreService.log.info("开始上传文件中，文件为mp3格式，需要转成wav");
		// 生成wav存放地址
		String completeFileName2 = completeFileName.substring(0, completeFileName.lastIndexOf(".")) + ".wav";
		// 把mp3格式转化为wav格式
		boolean res = ConvertAudio.convert2(completeFileName, completeFileName2);
		if (res) {
		    CoreService.log.info("开始上传文件中，文件为mp3格式，需要转成wav,转换成功" + fileName);
		    completeFileName = completeFileName2;
		} else {
		    CoreService.log.info("开始上传文件中，文件为mp3格式，需要转成wav,转换失败" + fileName);

		    bean.setResult("-1");
		    bean.setFileName("");
		    return bean;
		}
	    }
	    String response = MediaFileUpload(fileName, completeFileName);
	    remind(response, RemindEnum.OPEN_UPLOADFILE_RONGLIAN.getKey(), RemindEnum.OPEN_UPLOADFILE_RONGLIAN.getValue());
	    Document doc = DocumentHelper.parseText(response);
	    Element root = doc.getRootElement();
	    String result = root.elementTextTrim("statusCode");
	    if (StringUtils.isNotBlank(result) && result.equals("000000")) {
		result = "0";
	    } else {
		result = "-1";
	    }
	    String downloadUrl = root.elementTextTrim("downloadUrl");
	    Long end = Calendar.getInstance().getTimeInMillis();
	    Double during = Double.valueOf((end - begin)) / 1000;
	    logService.logIms(during, "UploadFile", "上传文件-ronglian-" + fileName, "【" + response + "】", result + "", currentTime, "RongLian", "");
	    bean.setResult(result);
	    bean.setFileName(downloadUrl);
	    return bean;
	} catch (Exception e) {
	    e.printStackTrace();
	    logService.logIms(0, "UploadFile", "上传文件-ronglian-" + fileName, "【" + e.getMessage() + "】", "-1", currentTime, "RongLian", "");
	}
	bean.setResult("999999");
	bean.setFileName("");
	return bean;
    }

    /**
     * 荣联上传语音文件
     * 
     * @param fileName
     *            文件名唯一
     * @param filePath
     *            二进制数据
     * @return
     */
    private static String MediaFileUpload(String fileName, String filePath) {
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/Calls/MediaFileUpload?sig="
		+ getSignature(AccountSid, AccountToken) + "&appid=" + AppId + "&filename=" + fileName;
	return HttpRequest.postRongLianFile(AccountSid, timestamp, url, filePath);
    }

    /**
     * 提醒
     * 
     * @param response
     * @param abilityType
     * @throws DocumentException
     */
    public static void remind(String response, String abilityType, String content) {
	if (StringUtils.isNotBlank(response)) {

	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		String result = root.elementTextTrim("statusCode");
		String desc = root.elementTextTrim("statusMsg");
		if (StringUtils.isBlank(result)) {// 返回无状态码与错误信息
		    RemindUtils.remind(abilityType, content + ":" + response, "sms");
		} else if (result.equals("108041")) {// 显号不对
		    RemindUtils.remind(abilityType, content + ":" + "customerSerNum为空或者错误", "sms");
		} else if (result.equals("111007") && result.equals("111014")) {// 内部错误
		    RemindUtils.remind(abilityType, content + ":" + desc, "sms");
		} else if (result.equals("121002")) {// 呼叫鉴权，余额不足
		    RemindUtils.remind(abilityType, content + ":" + desc, "sms");
		} else if (result.equals("113223")) {// 【合作方】语音文件剩余空间不足
		    RemindUtils.remind(abilityType, content + ":" + desc, "sms");
		} else if (result.equals("112580")) {// 【合作方】文件保存失败
		    RemindUtils.remind(abilityType, content + ":" + desc, "sms");
		} else if (result.equals("612597")) {
		    RemindUtils.remind(abilityType, content + ":" + "未知错误", "sms");
		} else if (result.equals("000000")) {// 000000 成功

		} else {
		    // RemindUtils.remind(abilityType, content + ":" + desc,
		    // "email2");
		}
	    } catch (DocumentException e) {
		RemindUtils.remind(abilityType, content + ":" + response, "sms");
	    }

	} else {
	    RemindUtils.remind(abilityType, content + ":接口响应为空", "sms");
	}
    }

    // MD5加密
    private static String md5Digest(String src) throws Exception {
	MessageDigest md = MessageDigest.getInstance("MD5");
	byte[] b = md.digest(src.getBytes("utf-8"));
	return byte2HexStr(b);
    }

    /**
     * 生成密钥
     * 
     * @return
     */
    private static String getSignature(String sid, String token) {
	// 获取系统时间
	SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
	timestamp = df.format(new Date());
	// 生成sig
	String signature = "";
	String sig = sid + token + timestamp;

	try {
	    signature = md5Digest(sig);
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return signature;
    }

    private static String byte2HexStr(byte[] b) {
	StringBuilder sb = new StringBuilder();
	for (int i = 0; i < b.length; ++i) {
	    String s = Integer.toHexString(b[i] & 0xFF);
	    if (s.length() == 1)
		sb.append("0");

	    sb.append(s.toUpperCase());
	}
	return sb.toString();
    }

    /**
     * 荣联IVR外呼功能
     * 
     * @param number
     * @param userdata
     *            {"type":"tts/voice","voicename":"","ttscontent":""}
     * @param record
     * @param sso
     *            .getFile("201610091054514232.mp3",
     *            "D:\\201610091054514232.mp3"); ivr结束提示音
     * @return
     */
    public static String Ivrdail(String number, String userdata, String record) {

	// 拼接请求包体
	String requsetbody = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?><Request>");
	sb.append("<Appid>").append(AppId).append("</Appid>");
	sb.append("<Dial number=").append("\"").append(number).append("\"");
	if (record != null) {
	    sb.append(" record=").append("\"").append(record).append("\"");
	}
	if (userdata != null) {
	    sb.append(" userdata=").append("\"").append(userdata).append("\"");
	}
	sb.append("></Dial></Request>").toString();
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/ivr/dial?sig=" + getSignature(AccountSid, AccountToken);
	return HttpRequest.sendRongLianPost(AccountSid, timestamp, url, requsetbody);
    }

    /**
     * 荣联语音验证码
     * 
     * @param number
     * @param verifyCode
     * @param userdata
     * @return
     */
    public static String VoiceVerify(String number, String verifyCode, String userdata) {
	// 拼接请求包体
	String requsetbody = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?><VoiceVerify>");
	sb.append("<appId>").append(AppId).append("</appId>");
	sb.append("<verifyCode>").append(verifyCode).append("</verifyCode>");// 验证码内容，为数字和英文字母，不区分大小写，长度4-8位。
	sb.append("<to>").append(number).append("</to>");
	sb.append("<playTimes>2</playTimes>");// 循环播放次数，1－3次，默认播放1次。
	if (userdata != null) {
	    sb.append(" userdata=").append("\"").append(userdata).append("\"");
	}
	sb.append("</VoiceVerify>");
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/Calls/VoiceVerify?sig=" + getSignature(AccountSid, AccountToken);
	return HttpRequest.sendRongLianPost(AccountSid, timestamp, url, requsetbody);
    }

    /**
     * 容联删除已上传的语音文件
     * 
     * @param voice_name
     * @return
     */
    public static JSONObject DelMediaFile(String voice_name) {
	JSONObject object = new JSONObject();
	// 拼接请求包体
	String requsetbody = "";
	StringBuilder sb = new StringBuilder("<?xml version='1.0' encoding='utf-8'?>");
	sb.append("<Request>");
	sb.append("<appId>").append(AppId).append("</appId>"); // 应用ID
	sb.append("<fileName>").append(voice_name).append("</fileName>"); // 文件名称
	sb.append("</Request>");
	requsetbody = sb.toString();
	String url = "https://" + ServerIP + ":" + ServerPort + "/" + SoftVersion + "/Accounts/" + AccountSid + "/DelMediaFile?sig=" + getSignature(AccountSid, AccountToken);

	String response = HttpRequest.sendRongLianPost(AccountSid, timestamp, url, requsetbody);
	String result = "";
	if (StringUtils.isNotBlank(response)) {
	    try {
		Document doc = DocumentHelper.parseText(response);
		Element root = doc.getRootElement();
		result = root.elementTextTrim("statusCode");
		if (result.equals("000000")) {
		    result = "0";
		} else {
		    result = "-1";
		}
	    } catch (DocumentException e) {
		result = "-1";
		e.printStackTrace();
	    }
	} else {
	    result = "-1";
	    response = "";
	}

	object.put("result", result);
	object.put("discripe", "");
	return object;
    }
}
